﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using NJamb.Parser.SubjectBuilders;
using NJamb.Specifications.Delta;
using NJamb.Specifications.Simple.Singular;
using NUnit.Framework;
using Stile.NUnit;
using Stile.Readability;
using Stile.Testing.SampleTypes;
#endregion

namespace NJamb.Tests
{
	[TestFixture]
	public class ExperimentFixture : SampleFixture
	{
		private ISingularSpecification<string> _before;
		private IDeltaSpecification _deltaSpecificationThatPassesBefore;
		private Experiment<Sample> _testSubject;

		[Test]
		public void FailingBeforeDoesNotEvaluateTryAction()
		{
			ISingularSpecification<string> singularSpecification =
				Specify.For(() => _sample).That(x => x.String).Is.Not.EqualTo(_sample.String);
			Assert.That(singularSpecification.Evaluate().Success, Is.False, "Precondition");
			var testSubject = new Experiment<Sample>(_sample, singularSpecification.AndLater.Is.EqualTo(string.Empty));
			Assert.That(testSubject.Specifications[0].EvaluatePrecondition().Evaluation.Success, Is.False);

			// arrange
			bool onFailCalled = false;
			bool tryCalled = false;
			bool successCalled = false;

			// act
			bool passed = testSubject.Try(x => tryCalled = true, s => onFailCalled = true, x => successCalled = true);

			// assert
			Assert.That(passed, Is.False);
			Assert.That(onFailCalled, Is.True);
			Assert.That(tryCalled, Is.False);
			Assert.That(successCalled, Is.False);
		}

		[Test]
		public void PassingBeforeEvaluatesTryAction()
		{
			Assert.That(_testSubject.Specifications.Count, Is.EqualTo(1));
			Assert.That(_testSubject.Specifications[0].EvaluatePrecondition().Evaluation.Success, Is.True);

			// arrange
			bool tryCalled = false;

			// act
			bool passed = _testSubject.Try(x => tryCalled = true, s => {});

			// assert
			Assert.That(passed, Is.False);
			Assert.That(tryCalled, Is.True);
		}

		[Test]
		public void PassingBeforeEvaluatesSuccessCallback()
		{
			Assert.That(_testSubject.Specifications.Count, Is.EqualTo(1));
			Assert.That(_testSubject.Specifications[0].EvaluatePrecondition().Evaluation.Success, Is.True);

			// arrange
			bool successCalled = false;

			// act
			bool passed = _testSubject.Try(Empty.ActionOn<Sample>, s => { }, x => successCalled = true);

			// assert
			Assert.That(passed, Is.False);
			Assert.That(successCalled, Is.True);
		}

		[Test]
		public void Subject()
		{
			Assert.That(_testSubject.Subject, Is.SameAs(_sample));
		}

		protected override void SetupComplete()
		{
			_before = Specify.For(() => _sample).That(x => x.String).Is.EqualTo(Null.String);
			_deltaSpecificationThatPassesBefore = _before.AndLater.Is.EqualTo(string.Empty);

			_testSubject = new Experiment<Sample>(_sample, _deltaSpecificationThatPassesBefore);
		}
	}
}
